package com.practice.car.cardataapp.schelduer.scrapy;

import com.practice.car.cardataapp.schelduer.spark.Schedule;
import lombok.Getter;
import lombok.Setter;

import java.io.*;
import java.io.IOException;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;

/**
 * car-data-app project
 *
 * @author 叶旺江
 * @date 2020/9/8
 */


public class ScrapyScheduler {

    @Getter
    @Setter
    public static boolean isContinue = false;
    public static boolean isRun = false;
    public static Timer timer;
    //测试代码
    public ScrapyScheduler(){
        monitor();
    }
    private void monitor() {
        Timer timer = new Timer();
        long intevalPeriod = 24* 60 * 60 * 1000;//7*60000ms=7min调度一次  一天检查一次是否要停下或者启动
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                if (ScrapyScheduler.isContinue&& ScrapyScheduler.timer == null) {
                    ScrapyScheduler.run();
                } else if (!ScrapyScheduler.isContinue&& ScrapyScheduler.timer != null) {
                    ScrapyScheduler.timer.cancel();
                    ScrapyScheduler.timer=null;
                }
            }
        }, 0L, intevalPeriod);
    }

    public static void run() {
        isContinue = true;
        if (timer != null) {
            if (ScrapyScheduler.isRun) {
                return;
            }
            timer.cancel();
            timer.purge();
            timer = null;
        }
        dispatch();
    }

    //通过读取resources下scrapy_data.properties文件的cmd命令  调度爬虫
    public static void dispatch() {
        timer = new Timer();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                ScrapyScheduler.isRun = true;
                synchronized (Schedule.lock) {
                    System.out.println("正在处理旧数据。。。。");
                    //处理旧数据
                    Hdfs.handleOldData();

                    System.out.println("正在执行爬虫。。。。");
                    String scrapy1;
                    String scrapy2;
                    String scrapy3;
                    String scrapy4;
                    String scrapy5;

                    //加载资源文件，resources下的scrapy_data.properties
                    InputStream is = ScrapyScheduler.class.getClassLoader().getResourceAsStream("scrapy_data.properties");
                    Properties properties = new Properties();
                    try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is))) {
                        properties.load(bufferedReader);
                        //读取scrapy命令
                        scrapy1 = properties.getProperty("command_add_national");
                        scrapy2 = properties.getProperty("command_origin");
                        scrapy3 = properties.getProperty("command_complaints");
                        scrapy4 = properties.getProperty("command_car_sub");
                        scrapy5 = properties.getProperty("command_grade");

                        //调度爬虫程序
                        cmd(scrapy5);
                        cmd(scrapy1);
                        cmd(scrapy2);
                        cmd(scrapy3);
                        cmd(scrapy4);
                        Hdfs.uploadFiles();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }finally {
                        ScrapyScheduler.isRun = false;
                    }
                }
            }
        };
        //30天调度一次
        timer.schedule(task, 5000 , Long.parseLong("2592000000"));

    }

    //通过命令行执行 cmd 命令
    public static void cmd(String command){
        Process proc = null;
        try {
            //执行命令行
            proc = Runtime.getRuntime().exec(command);
            printMessage(proc.getInputStream()); //读取进程的标准输出
            printMessage(proc.getErrorStream()); //读取进程的标准错误输出
            int t=proc.waitFor();
            if(t == 0)
                System.out.println("命令："+command+"  命令执行成功！");
            else
                System.out.println("命令："+command+"  命令执行失败！");

        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            //关闭子进程
            if(proc != null)
                proc.destroy();
        }
    }

    //通过输入流读取进程信息，这个必须读取且必须采用多线程，否则会出现进程挂起
    private static void printMessage(final InputStream input ) {
        new Thread(new Runnable() {
            public void run() {
                BufferedReader bufferedReader = null;
                String line = null;
                //注意编码问题，windows命令行的默认编码为GBK,linux---utf-8
                try {
                    bufferedReader = new BufferedReader(new InputStreamReader(input,"UTF-8"));
                    while((line=bufferedReader.readLine())!=null) {
                        System.out.println("*****" + line);
                    }
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }catch(IOException e){
                    e.printStackTrace();
                }
                finally{
                    if(bufferedReader != null)
                        try {
                            bufferedReader.close();
                        }catch(IOException e){
                            e.printStackTrace();
                        }
                }
            }
        }).start();
    }

}

